<template>
  <el-dialog
    v-bind="$attrs"
    title="选择父级菜单"
    width="650"
    :before-close="beforeClose"
    :close-on-click-modal="false"
  >
    <div class="container">
      <el-tree
        ref="treeRef"
        node-key="_id"
        :data="treeData"
        highlight-current
        default-expand-all
        :expand-on-click-node="false"
        :props="treeProps"
        @node-click="handleNodeClick"
      >
        <template #default="{ data }">
          <span class="icon" v-if="!data?.children.length">
            <el-icon v-if="data.type == 0"><Folder /></el-icon>
            <el-icon v-if="data.type == 1"><Menu /></el-icon>
            <el-icon v-if="data.type == 2"><Lock /></el-icon>
          </span>
          <span class="icon" v-else @click.stop="handleIconClick(data)">
            <el-icon v-if="isOpen(data)"><Remove /></el-icon>
            <el-icon v-else><CirclePlus /></el-icon>
          </span>
          <span>{{ data.title }}</span>
        </template>
      </el-tree>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, markRaw, ref } from 'vue'
import { Menu, Remove, CirclePlus, Folder, Lock } from '@element-plus/icons-vue'
import { MenuApi } from '@/api/interface/menu'

defineProps(['treeData'])
const emit = defineEmits(['update:modelValue', 'confirm'])
const treeProps = markRaw({
  children: 'children',
  label: 'title'
})
const treeRef = ref()
const beforeClose = () => {
  emit('update:modelValue', false)
}
const isOpen = computed(() => {
  return function (data: MenuApi.Menu) {
    return treeRef.value?.store.nodesMap[data._id].expanded
  }
})
const handleNodeClick = (data: MenuApi.Menu) => {
  emit('confirm', data)
  emit('update:modelValue', false)
}
const handleIconClick = (data: MenuApi.Menu) => {
  treeRef.value.store.nodesMap[data._id].expanded =
    !treeRef.value.store.nodesMap[data._id].expanded
}
</script>

<style lang="scss" scoped>
.container {
  padding: 20px;
}

::v-deep .el-tree {
  .icon {
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 5px 0 5px;
    font-size: 18px !important;
    color: #1989fa;
  }

  .el-tree-node {
    position: relative;
    padding-left: 10px;
  }

  .el-tree-node__children {
    padding-left: 25px;
  }

  .el-tree-node :last-child::before {
    height: 40px;
  }

  .el-tree > .el-tree-node:before {
    border-left: none;
  }

  .el-tree > .el-tree-node:after {
    border-top: none;
  }

  .el-tree-node:before,
  .el-tree-node:after {
    content: '';
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }

  .el-tree-node:before {
    border-left: 2px dotted #1989fa;
    bottom: 0;
    height: 99%;
    left: -3px;
    top: -25px;
    width: 1px;
  }

  .el-tree-node:after {
    border-top: 2px dotted #1989fa;
    left: 0;
    height: 20px;
    top: 14px;
    width: 24px;
  }

  .el-tree-node__expand-icon.is-leaf {
    width: 8px;
  }

  .el-tree-node__content > .el-tree-node__expand-icon {
    display: none;
  }

  .el-tree-node__content {
    line-height: 30px;
    height: 30px;
    padding-left: 10px !important;
  }
}

::v-deep .el-tree > div {
  &::before,
  &::after {
    display: none;
  }
}
</style>
